﻿#pragma once
#include <stdio.h>
#include <string.h>
#include <vector>
#include<iostream>
#include<thread>

#/*include "AlazarApi.h"
#include "AlazarCmd.h"
#include "AlazarDSP.h"
#include "AlazarError.h"*/

#include "Definitions.h"

#include <list>

#include "kernel_stream_SAD_fixedarea.h"

#ifdef _WIN32
#include <conio.h>
#else // ifndef _WIN32

#include <errno.h>
#include <math.h>
#include <signal.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#pragma comment(lib,"ATS_CUDA_OCT.lib")
#pragma comment(lib,"ATS_GPU_OCT.lib")
#define TRUE 1
#define FALSE 0

#define _snprintf snprintf

inline U32 GetTickCount(void);
inline void Sleep(U32 dwTime_ms);
inline int _kbhit(void);
inline int GetLastError();
#endif // ifndef _WIN32

//opencv

#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc/types_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/highgui/highgui_c.h"

#include <QtCore/qdebug.h>
#include <QtCore/qfile.h>
#include <QtCore/QObject>
#include <QtGui/QImage>
#include <QtCore/qstring.h>
#include <process.h>
#include<QFileDialog>
#include<QMovie>

#include "cuFloatComplex.h"

//#include "ATS_CUDA.h"
//#include "ATS_CUDA_OCT.h"
//#include "ATS_GPU.h"
//#include "ATS_GPU_OCT.h"



#include<algorithm>
#include <iostream>
#include <windows.h>
#include <conio.h>

#include <QtSerialPort/QSerialPort> 
#include <QtSerialPort/QSerialPortInfo>  

using namespace std;
using namespace cv;

#define ERROR_CHECK(x)                                                         \
    do {                                                                       \
        RETURN_CODE retCode = (x);                                             \
        if (retCode != ApiSuccess) {                                           \
            qDebug("Error: %s failed with %s\n", #x,                           \
                   AlazarErrorToText(retCode));                                \
            success = FALSE;                                                   \
            goto exit;                                                         \
        }                                                                      \
    } while (0)


#define BUFFER_COUNT 4
#pragma execution_character_set("utf-8")

class Alazar : public QObject
{
	Q_OBJECT
public:
	~Alazar();
	static Alazar * Getalazar();
	static void ReleaseInstance();
	void start();
	void stop();
	void setTriAndDepth(int A_scan, int B_scan, int C_scan);
	void getSpectralSignal(void*buffers, float*m_Struoutput_frame, unsigned short*m_spectralsignal);

	// 串口
	void SetCOM(int EPOS_COM);
	void DocSend(int step);
	void DirSend(int step);
	void SpeedSend(int step);

	// 后添加

	void CloseThread();
	void SaveStart();
	void TestDemo();
	void ReadColorBar();

	ushort *Save_Data;
	ushort *Save_Data_Temp;
	int SaveDataBool=0;
	int A_scan, B_scan, C_scan;// 采集所需的参数设置
	// Linchart 显示所需参数
	int LineShow_Local_Optic = 0, LineShow_Local_Gray = 0;
	int LineShow_Local_Optic_Now = 0, LineShow_Local_Gray_Now = 0;
	bool LineShow_bool = false;

	// 图片储存
	bool Save_Image_Str = false, Save_File_Optic = true;
	
	// 伪彩色
	int Throld_BW = 63;
	bool BleedFiter = false;
	int CenterFill_Pixel = 0;

	bool ShowColor;
	bool SaveTemp = true;
	QString PatientName;

	U32 deviceCount = 0;
	U32 deviceIndex = 0;
	char deviceName[256];
	QString ColorMap_Name;

	float s2 = 8E+7;//原来师姐4e+9
	HANDLE hDevice = NULL;//ART
	QString Path_Save_All = ".";

	// 结束

signals:
	void ImageComplete(const Mat & m_mat);
	void SignalComplete(const unsigned short* m_spectralsignal);
	void FFTOutputComplete(const float*m_FFTOutput);

	// 后添加
	void TextShow(const QString OutText);

	void CaputureEnd();
	void SaveEnd();
	void ColorMapRefresh(QImage ColorBar);
	void OpenSignal();

	void setSliderMaxSave(int value_Save);
	void setSliderMaxScan(int value_Scan);
	void setSliderValue(int value_Scan, int value_Save);

private:
	BOOL ConfigureBoard(HANDLE boardHandle);
	BOOL AcquireDataGPU();
	void SignalStart();

	
	// Globals variables
	ushort* BufferArray[BUFFER_COUNT];
	double samplesPerSec;
	
	bool has_alazar;
	bool success;
	U32 systemId;
	U32 boardId;

	

	unsigned short*m_spectralsignal = nullptr;
	
	HANDLE m_boardHandle = NULL;
	HANDLE m_image_thread = NULL;
	HANDLE m_signal_thread = NULL;
	
	bool Handle_Creat = false;
	
	// 存储数据
	static Alazar*m_alazar_instance;
	static unsigned __stdcall ImageProcess(void* param);
	static unsigned __stdcall FileInwriteData(void* param);

	QImage Mat2QImageRGB(const Mat& src_mat);

	

	// 电机
	__int8 m_bMode;
	BOOL m_oImmediately;
	BOOL m_oInitialisation;
	BOOL m_oUpdateActive;
	DWORD m_ulErrorCode;
	DWORD m_ulProfileAcceleration;
	DWORD m_ulProfileDeceleration;
	DWORD m_ulProfileVelocity;
	HANDLE m_KeyHandle;
	WORD m_usNodeId = 1;
	int     m_oRadio;
	long    m_lActualValue;
	long    m_lStartPosition = 20;
	long    m_lTargetPosition = 2000;

	HANDLE Epos_test;

	bool EPOS_InitDevice();
	bool EPOS_StartMove(long TargetVelocity);
	bool EPOS_StopMove();
	bool EPOS_IsMove();
	bool EPOS_CloseDevice();

	void EPOS_ShowError(DWORD m_ulErrorCode);
	// End




	int m_iferror;
	bool PCIend=false;
	bool startPCI = false;

	void *buffers[12];


	//显示矩阵
	Mat* show_save_str;
	int Save_Str = 0;
	float *output_stru = nullptr;
	unsigned char* show_stru = nullptr;					// B_Scan结构


	Alazar();
	

	///后添加
	// Slider change signal
	int OtsuAlgThreshold(const Mat image);
	void Clear_MicroConnected_Areas(cv::Mat src, cv::Mat& dst, double min_area);

	void InitShowMat();
	void AveFilter(unsigned char* Input, unsigned char* Output, int col,int raw, int kernelsize,bool cover);
	void MinFilter(unsigned char* Input, unsigned char* Output, int col, int raw, int kernelsize, bool cover);

	int SliderValue, AveValue;
	U32 buffersCompleted, buffersCompleted_Temp=0;
	double ConValue;
	int StartLocal;
	bool SliderChange,SaveData,InitOver;
	HANDLE m_savefile_thread = NULL,m_saveimage_thread = NULL;
	
	// 串口电机
	int EPOS_COM = 5;




	// End

	// 串口工具(参数)
	QSerialPort* serial;
	// 串口工具(函数)
	void SerialPortFind();
	bool SerialPortInit();
	void OutSignal();

	// 存储
	int FileNum;
	
	QString File_DirPath = ".";

	//伪彩色需要
	double* colorbar; 
	Mat projection_Vas_Color;
	
	Mat MatGray2RGB(Mat Mat_Input);
	

	//控制ATS
	bool ATSKeepMoving = true, NIKeepMoving = true;

};